package com.ruowei.modules.foodOrder.service;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ruowei.common.error.exception.BadRequestAlertException;
import com.ruowei.common.error.exception.CommonException;
import com.ruowei.modules.foodOrder.domain.*;
import com.ruowei.modules.foodOrder.domain.enumeration.FlowType;
import com.ruowei.modules.foodOrder.domain.enumeration.OrderStatus;
import com.ruowei.modules.foodOrder.pojo.dto.*;
import com.ruowei.modules.foodOrder.repository.*;
import com.ruowei.modules.member.domain.Member;
import com.ruowei.modules.sys.utils.AppletTokenUtils;
import com.ruowei.modules.sys.utils.CommonUtils;
import com.ruowei.modules.sys.utils.RedisUtil;
import com.ruowei.modules.webSocket.domain.enumeration.MessageType;
import com.ruowei.modules.webSocket.domain.enumeration.ReceiverType;
import com.ruowei.modules.webSocket.domain.enumeration.SenderType;
import com.ruowei.modules.webSocket.service.MessagePushService;
import com.ruowei.modules.wxpay.service.PayReturnService;
import com.ruowei.modules.wxpay.service.WeChatPayService;
import com.ruowei.modules.wxpay.utils.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.*;

@Service
@Slf4j
@Transactional
public class OrderService {

    private final QShoppingCart qShoppingCart = QShoppingCart.shoppingCart;

    private final JPAQueryFactory jpaQueryFactory;
    private final MerchandiseSkuRepository skuRepository;
    private final MerchandiseRepository merchandiseRepository;
    private final MerchantRepository merchantRepository;
    private final OrderRepository orderRepository;
    private final OrderItemRepository itemRepository;
    private final WeChatPayService payService;
    private final MessagePushService messagePushService;
    private final RefundApplicationRepository refundApplicationRepository;
    private final OrderLifeCycleRepository lifeCycleRepository;
    private final LifeCycleService lifeCycleService;
    private final PayReturnService payReturnService;
    private final PaymentFlowService paymentFlowService;
    private final MerchantService merchantService;

    public OrderService(JPAQueryFactory jpaQueryFactory, MerchandiseSkuRepository skuRepository,
                        MerchandiseRepository merchandiseRepository, MerchantRepository merchantRepository,
                        OrderRepository orderRepository, OrderItemRepository itemRepository,
                        WeChatPayService payService, MessagePushService messagePushService,
                        RefundApplicationRepository refundApplicationRepository,
                        OrderLifeCycleRepository lifeCycleRepository, LifeCycleService lifeCycleService,
                        PayReturnService payReturnService, PaymentFlowService paymentFlowService, MerchantService merchantService) {
        this.jpaQueryFactory = jpaQueryFactory;
        this.skuRepository = skuRepository;
        this.merchandiseRepository = merchandiseRepository;
        this.merchantRepository = merchantRepository;
        this.orderRepository = orderRepository;
        this.itemRepository = itemRepository;
        this.payService = payService;
        this.messagePushService = messagePushService;
        this.refundApplicationRepository = refundApplicationRepository;
        this.lifeCycleRepository = lifeCycleRepository;
        this.lifeCycleService = lifeCycleService;
        this.payReturnService = payReturnService;
        this.paymentFlowService = paymentFlowService;
        this.merchantService = merchantService;
    }

    public List<OrderLifeCycle> orderTracking(String orderCode, HttpServletRequest request) {
        Member member = AppletTokenUtils.getOpenIdByToken(request);
        return lifeCycleRepository.findByOrderCodeOrderByTimeAsc(orderCode);
    }

    public OrderDetailDTO getOrderDetail(String orderCode, HttpServletRequest request) {
        Member member = AppletTokenUtils.getOpenIdByToken(request);
        Order order = orderRepository.findByOrderCode(orderCode).orElseThrow(() -> new CommonException("未找到该订单"));
        Merchant merchant = merchantRepository.findByMerchantCode(order.getMerchantCode()).orElseThrow(() -> new CommonException("商家不存在"));
        List<OrderItem> items = itemRepository.findAllByOrderCode(orderCode);

        BigDecimal totalAmount = BigDecimal.ZERO;
        BigDecimal payAmount = BigDecimal.ZERO;
        BigDecimal totalPackingFee = BigDecimal.ZERO;
        List<DetailItemDTO> detailItemDTOS = new ArrayList<>();

        for (OrderItem item : items) {
            totalAmount = totalAmount.add(item.getOriginUnitPrice());
            payAmount = payAmount.add(item.getUnitPrice());
            totalPackingFee = totalPackingFee.add(item.getPackingFee());

            DetailItemDTO detailItemDTO = new DetailItemDTO();
            detailItemDTO.setMerchandiseName(item.getMerchandiseName());
            detailItemDTO.setMerchandiseQuantity(item.getQuantity());
            detailItemDTO.setMerchandisePhoto(item.getPhotos());
            detailItemDTO.setMerchandisePrice(item.getUnitPrice());
            detailItemDTO.setSku(item.getSpecification());
            detailItemDTO.setPackingFee(item.getPackingFee());
            detailItemDTOS.add(detailItemDTO);
        }

        return new OrderDetailDTO(order.getStatus().getMessage(), order.getReceiverName(), order.getReceiverPhone(), order.getReceiverAddress(),
            order.getCreateTime(), Instant.now(), order.getPayType(), order.getCourierCode(), order.getCourierName(), order.getCourierPhone(),
            order.getRemark(), merchant.getMerchantCode(), merchant.getMerchantName(), merchant.getPhotos(), merchant.getPhone(), totalAmount,
            payAmount, totalPackingFee, detailItemDTOS);
    }

    public RefundOrderDetailDTO refundOrderDetail(String orderCode, HttpServletRequest request) {
        Member member = AppletTokenUtils.getOpenIdByToken(request);
        Order order = orderRepository.findByOrderCode(orderCode).orElseThrow(() -> new CommonException("未找到该订单"));

        Optional<RefundApplication> applicationOptional = refundApplicationRepository.findFirstByOrderCodeOrderByTimeDesc(orderCode);
        BigDecimal refundFee = BigDecimal.ZERO;
        String reason = "";
        if (applicationOptional.isPresent()) {
            refundFee = applicationOptional.get().getReturnAmount();
            reason = applicationOptional.get().getReason();
        } else if (order.getStatus().equals(OrderStatus.MERCHANT_REFUSE_TO_RECEIVE) ||
            order.getStatus().equals(OrderStatus.REFUNDING) ||
            order.getStatus().equals(OrderStatus.REFUNDED)) {
            refundFee = order.getPayAmount();
        }
        Merchant merchant = merchantRepository.findByMerchantCode(order.getMerchantCode()).orElseThrow(() -> new CommonException("商家不存在"));
        List<OrderItem> items = itemRepository.findAllByOrderCode(orderCode);
        List<OrderLifeCycle> lifeCycles = lifeCycleRepository.findByOrderRerunCodeIsNotNullAndOrderCodeOrderByTimeAsc(orderCode);

        RefundOrderDetailDTO detailDTO = new RefundOrderDetailDTO();
        detailDTO.setMerchantName(merchant.getMerchantName());
        detailDTO.setMerchantPhone(merchant.getPhone());
        detailDTO.setRefundFee(refundFee);
        detailDTO.setAddress(order.getReceiverAddress());
        detailDTO.setMemberName(order.getReceiverName());
        detailDTO.setMemberPhone(order.getReceiverPhone());
        detailDTO.setOrderCode(orderCode);
        detailDTO.setReason(reason);
        detailDTO.setCreateTime(order.getCreateTime());
        detailDTO.setStatus(order.getStatus().getMessage());

        List<OrderItemDTO> orderItemDTOS = new ArrayList<>();
        for (OrderItem orderItem : items) {
            OrderItemDTO dto = new OrderItemDTO();
            dto.setMerchandiseName(orderItem.getMerchandiseName());
            dto.setUnitPrice(orderItem.getUnitPrice());
            dto.setPhotos(orderItem.getPhotos());
            dto.setQuantity(orderItem.getQuantity());
            dto.setSpecification(orderItem.getSpecification());
            orderItemDTOS.add(dto);
        }

        List<LifeStyleDTO> lifeStyleDTOS = new ArrayList<>();
        for (OrderLifeCycle lifeCycle : lifeCycles) {
            LifeStyleDTO dto = new LifeStyleDTO();
            dto.setTitle(lifeCycle.getTitle());
            dto.setDescription(lifeCycle.getDescription());
            dto.setTime(lifeCycle.getTime());
            lifeStyleDTOS.add(dto);
        }

        detailDTO.setMerchandiseList(orderItemDTOS);
        detailDTO.setLifeStyle(lifeStyleDTOS);
        return detailDTO;
    }

    public Map<String, String> cancelOrder(String orderCode, HttpServletRequest request) {
        Member member = AppletTokenUtils.getOpenIdByToken(request);
        Map<String, String> result;
        Order order = orderRepository.findByOrderCode(orderCode).orElseThrow(() -> new CommonException("未找到该订单"));

        //调用退款接口
        try {
            result = payService.refund(order.getPayAmount(), orderCode);
        } catch (Exception e) {
            e.printStackTrace();

            payReturnService.saveFailedRecord(orderCode, null, order.getPayAmount(), null,
                null, null, e.getMessage(), null, null);

            log.error("取消订单失败，{},{}", e.getMessage(), e.toString());
            throw new CommonException("取消订单失败，请重试");
        }
        if (order.getStatus().equals(OrderStatus.TO_BE_PAID) && order.getPaymentTime() == null) {
            if (result.get("err_code_des") != null && result.get("err_code_des").equals("订单不存在")) {
                //商家未接单且未支付完成 直接取消
                order.setStatus(OrderStatus.CANCELLED);
                order.setUpdateTime(Instant.now());
                orderRepository.saveAndFlush(order);
                result.put("message", "订单取消成功");
                lifeCycleService.saveLifeCycle(orderCode, "", "订单已取消", "订单已取消");
                return result;
            }
        }

        if (!order.getStatus().equals(OrderStatus.TO_BE_RECEIVED)) {
            throw new CommonException("该订单已被商家处理，请联系商家退款");
        }

        if (org.apache.commons.lang3.StringUtils.isNotEmpty(result.get("return_msg")) && !result.get("return_msg").equals("OK")) {
            payReturnService.saveFailedRecord(orderCode,
                result.get("out_refund_no"),
                order.getPayAmount(),
                result.get("return_msg"),
                result.get("result_code"),
                result.get("err_code"),
                result.get("err_code_des"),
                result.get("transaction_id"),
                result.get("refund_id"));

            throw new CommonException(result.get("return_msg"));
        }
        if (!result.get("return_code").equals("SUCCESS") || !result.get("result_code").equals("SUCCESS")) {
            log.error("退款失败，{}", result.toString());
            payReturnService.saveFailedRecord(orderCode,
                result.get("out_refund_no"),
                order.getPayAmount(),
                result.get("return_msg"),
                result.get("result_code"),
                result.get("err_code"),
                result.get("err_code_des"),
                result.get("transaction_id"),
                result.get("refund_id"));

            throw new CommonException("退款失败:" + result.get("err_code_des"));
        }
        result.put("message", "申请退款成功，请留意退款到账");
        order.setUpdateTime(Instant.now());
        order.setStatus(OrderStatus.CANCELLING);
        orderRepository.saveAndFlush(order);

        lifeCycleService.saveLifeCycle(orderCode, result.get("out_refund_no") == null ? "" : result.get("out_refund_no"), "取消订单", "取消订单");
        lifeCycleService.saveLifeCycle(orderCode, result.get("out_refund_no") == null ? "" : result.get("out_refund_no"), "退款中", "退款中");

        RefundApplication refundApplication = new RefundApplication();
        refundApplication.setApplicationCode(CommonUtils.getUUID());
        refundApplication.setOrderCode(orderCode);
        refundApplication.setTime(Instant.now());
        refundApplication.setReturnAmount(order.getPayAmount());
        refundApplication.setStatus(OrderStatus.CANCELLING);
        refundApplicationRepository.save(refundApplication);

        Map<String, String> map = new HashMap<>();
        map.put("id", String.valueOf(order.getId()));
        map.put("orderCode", order.getOrderCode());
        map.put("status", order.getStatus().getMessage());
        messagePushService.pushMessage(SenderType.SYSTEM,
            null,
            order.getMerchantCode(),
            MessageType.FOOD_ORDER,
            true,
            "订单已取消",
            "有客户取消订单了，请及时查看",
            map,
            ReceiverType.MERCHANT_APP);

        return result;
    }

    public Map<String, String> returnApplication(String orderCode, BigDecimal returnAmount, String reason, String description, HttpServletRequest request) {
        Member member = AppletTokenUtils.getOpenIdByToken(request);
        Map<String, String> result = new HashMap<>();
        Order order = orderRepository.findByOrderCode(orderCode).orElseThrow(() -> new CommonException("未找到该订单"));
        if (order.getStatus().equals(OrderStatus.TO_BE_PAID) || order.getPaymentTime() == null) {
            throw new BadRequestAlertException("订单未支付成功，无法退款");
        }
        if (order.getStatus().equals(OrderStatus.DELIVERED)) {
            throw new CommonException("订单已送达，请联系商家退款");
        }
        order.setStatus(OrderStatus.REFUND_APPLYING);
        order.setUpdateTime(Instant.now());
        orderRepository.saveAndFlush(order);
        result.put("message", "申请退款成功，请等待商家处理");

        RefundApplication refundApplication = new RefundApplication();
        refundApplication.setApplicationCode(CommonUtils.getUUID());
        refundApplication.setOrderCode(orderCode);
        refundApplication.setTime(Instant.now());
        refundApplication.setReturnAmount(returnAmount);
        refundApplication.setStatus(OrderStatus.REFUND_APPLYING);
        refundApplication.setReason(reason);
        refundApplication.setDescription(description);
        refundApplicationRepository.save(refundApplication);

        //给商家发消息
        Map<String, String> customMessage = new HashMap<>();
        customMessage.put("id", String.valueOf(order.getId()));
        customMessage.put("orderCode", order.getOrderCode());
        messagePushService.pushMessage(SenderType.SYSTEM,
            null,
            order.getMerchantCode(),
            MessageType.FOOD_ORDER,
            true,
            "订单取消",
            "有客户发起订单取消了，请及时查看",
            customMessage,
            ReceiverType.MERCHANT_APP);

        if (org.apache.commons.lang3.StringUtils.isNotEmpty(order.getCourierCode())) {
            //给配送员发推送
            messagePushService.pushMessage(SenderType.SYSTEM, null, order.getCourierCode(), MessageType.FOOD_ORDER,
                true, "订单取消", "有客户发起订单取消了，请及时查看", customMessage, ReceiverType.COURIER_APP);
        }

        //保存退款进度
        lifeCycleService.saveLifeCycle(orderCode, refundApplication.getApplicationCode(), "退款申请中", "您的退款申请已发出，等待商家处理");

        return result;
    }

    public Map<String, String> getOrderStatus(String orderCode, HttpServletRequest request) throws Exception {
        Member member = AppletTokenUtils.getOpenIdByToken(request);
        Map<String, String> result = new HashMap<>();
        Order order = orderRepository.findByOrderCode(orderCode).orElseThrow(() -> new CommonException("未查询到该订单"));
        if (order.getStatus().equals(OrderStatus.TO_BE_RECEIVED)) {
            result.put("status", "成功");
            return result;
        }
        if (!order.getStatus().equals(OrderStatus.TO_BE_PAID) || order.getPaymentTime() != null) {
            result.put("status", "失败");
        } else {
            Map<String, String> map = payService.queryOrder(orderCode);
            if (map.get("return_code").equals("SUCCESS") &&
                map.get("result_code").equals("SUCCESS") &&
                map.get("trade_state").equals("SUCCESS")) {
                order.setStatus(OrderStatus.TO_BE_RECEIVED);
                order.setPaymentTime(Instant.now());
                order.setUpdateTime(Instant.now());
                orderRepository.saveAndFlush(order);
                result.put("status", "成功");

                lifeCycleService.saveLifeCycle(orderCode, null, "支付成功", "支付成功");

                //给商家发消息
                Map<String, String> customMessage = new HashMap<>();
                customMessage.put("id", String.valueOf(order.getId()));
                customMessage.put("orderCode", order.getOrderCode());
                messagePushService.pushMessage(SenderType.SYSTEM,
                    null,
                    order.getMerchantCode(),
                    MessageType.FOOD_ORDER,
                    true,
                    "新的订单",
                    "您有新的订单",
                    customMessage,
                    ReceiverType.MERCHANT_APP);
            } else {
                log.error(WXPayUtil.mapToXml(map));
                result.put("status", "失败");
            }
        }
        return result;
    }

    public Map<String, String> repay(String orderCode, HttpServletRequest request) {
        Member member = AppletTokenUtils.getOpenIdByToken(request);
        Order order = orderRepository.findByOrderCode(orderCode).orElseThrow(() -> new CommonException("未查询到该订单"));
        Merchant merchant = merchantRepository.findByMerchantCode(order.getMerchantCode()).orElseThrow(() -> new CommonException("商家不存在"));
        List<OrderItem> items = itemRepository.findAllByOrderCode(orderCode);

        if (order.getStatus().equals(OrderStatus.CANCELLED)) {
            throw new CommonException("订单已取消，请重新下单");
        }
        if (!order.getStatus().equals(OrderStatus.TO_BE_PAID)) {
            throw new CommonException("订单已支付，请勿重复支付");
        }
        String merchantName = merchant.getMerchantName();
        StringBuilder merchandiseName = new StringBuilder();
        for (OrderItem item : items) {
            merchandiseName.append(item.getMerchandiseName()).append(",");
        }
        if (merchandiseName.length() > 1) {
            merchandiseName.deleteCharAt(merchandiseName.length() - 1);
        }

        String[] merchandises = merchandiseName.toString().split(",");
        if (merchandises.length > 1) {
            merchandiseName = new StringBuilder();
            merchandiseName.append(merchandises[0]).append("等");
        }

        //调用微信支付接口

        return payService.unifiedOrder(request, merchantName + "-" + merchandiseName.toString(),
            order.getPayAmount().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString(), orderCode);
    }

    public Map<String, String> createOrder(String cartCodes, String receiverName, String receiverPhone, String receiverAddress, String remark, HttpServletRequest request) {
        Member member = AppletTokenUtils.getOpenIdByToken(request);
        //生成订单编码和订单主表
        String orderCode = WXPayUtil.createOrderCode();
        Order order = new Order();
        order.setOrderCode(orderCode);
        order.setCreateTime(Instant.now());
        order.setCreateDate(LocalDate.now());
        order.setMemberCode(member.getOpenId());

        //获取购物车列表
        List<ShoppingCart> carts = jpaQueryFactory.selectFrom(qShoppingCart)
            .where(qShoppingCart.cartCode.in(Arrays.asList(cartCodes.split(","))))
            .fetch();
        BigDecimal totalAmount = BigDecimal.ZERO;
        BigDecimal payAmount = BigDecimal.ZERO;
        String merchantName = "枫彩集团";
        String merchantCode = "";
        StringBuilder merchandiseName = new StringBuilder();
        StringBuilder invalidMerchandise = new StringBuilder();
        List<String> invalidCart = new ArrayList<>();
        List<OrderItem> items = new ArrayList<>();
        for (ShoppingCart cart : carts) {
            Optional<MerchandiseSku> skuOptional = skuRepository.findBySkuCodeAndStatus(cart.getSkuCode(), true);
            Optional<Merchandise> merchandiseOptional = merchandiseRepository.findFirstByMerchandiseCode(cart.getMerchandiseCode());
            Optional<Merchant> merchantOptional = merchantRepository.findByMerchantCode(cart.getMerchantCode());
            if (!cart.getMemberCode().equals(member.getOpenId())) {
                throw new CommonException("购物车信息与用户信息不符");
            }
            if (!merchandiseOptional.isPresent()) {
                jpaQueryFactory.delete(qShoppingCart)
                    .where(qShoppingCart.cartCode.in(Arrays.asList(cartCodes.split(","))))
                    .execute();
                throw new CommonException("订单内有不存在的商品，已清空购物车，请重新下单");
            }
            Merchandise merchandise = merchandiseOptional.get();

            if (merchandise.isDeleteStatus()) {
                //商品已删除
                invalidCart.add(cart.getCartCode());
                merchandiseRepository.findOneByMerchandiseCodeAndDeleteStatus(cart.getMerchandiseCode(), true)
                    .ifPresent(goods -> {
                        invalidMerchandise.append(goods.getMerchandiseName()).append(",");
                    });
                continue;
            }

            if (!merchandise.isPublishStatus()) {
                //商品已下架
                invalidCart.add(cart.getCartCode());
                invalidMerchandise.append(cart.getMerchandiseName()).append(",");
                continue;
            }

            if (!skuOptional.isPresent()) {
                //规格发生变化
                invalidCart.add(cart.getCartCode());
                invalidMerchandise.append(cart.getMerchandiseName()).append(",");
                continue;
            }

            if (!merchantOptional.isPresent()) {
                throw new CommonException("商家不存在");
            }
            Merchant merchant = merchantOptional.get();
            if (!merchant.getStatus().equals("营业")) {
                throw new CommonException("商家未营业，暂时无法接单");
            }
            merchantName = merchant.getMerchantName();
            order.setMerchantCode(merchantOptional.get().getMerchantCode());

            merchandiseName.append(merchandise.getMerchandiseName()).append(",");

            MerchandiseSku sku = skuOptional.get();
            totalAmount = totalAmount.add(sku.getUnitPrice().multiply(new BigDecimal(cart.getMerchandiseQuantity())));
            payAmount = payAmount.add(sku.getUnitPrice().multiply(new BigDecimal(cart.getMerchandiseQuantity())));
            //订单明细
            OrderItem orderItem = new OrderItem();
            orderItem.setItemCode(CommonUtils.getUUID());
            orderItem.setOrderCode(orderCode);
            orderItem.setMerchandiseCode(merchandise.getMerchandiseCode());
            orderItem.setMerchandiseName(merchandise.getMerchandiseName());
            orderItem.setSpecification(getSpecificationBySku(sku));
            orderItem.setPhotos(merchandise.getPhotos());
            orderItem.setUnitPrice(sku.getUnitPrice());
            orderItem.setOriginUnitPrice(sku.getUnitPrice());
            orderItem.setQuantity(cart.getMerchandiseQuantity());
            orderItem.setPackingFee(BigDecimal.ZERO);
            items.add(orderItem);
        }
        order.setTotalAmount(totalAmount);
        order.setPayAmount(payAmount);
        order.setPayType("微信支付");
        order.setStatus(OrderStatus.TO_BE_PAID);
        order.setReceiverName(receiverName);
        order.setReceiverPhone(receiverPhone);
        order.setReceiverAddress(receiverAddress);
        order.setRemark(remark);
        order.setConfirmStatus(false);
        order.setDeleteStatus(false);


        if (merchandiseName.length() > 0) {
            merchandiseName.deleteCharAt(merchandiseName.length() - 1);
        }

        if (invalidCart.size() > 0) {
            //自动删除无效购物车
            jpaQueryFactory.delete(qShoppingCart)
                .where(qShoppingCart.cartCode.in(invalidCart))
                .execute();
        }

        if (invalidMerchandise.length() > 0) {
            invalidMerchandise.deleteCharAt(invalidMerchandise.length() - 1);
            Map<String, String> result = new HashMap<>();
            result.put("code", "0");
            result.put("message", "当前购物车中" + invalidMerchandise.toString() + "已失效，已自动从购物车删除，请重新下单");
            return result;
        }
        String[] merchandises = merchandiseName.toString().split(",");
        if (merchandises.length > 1) {
            merchandiseName = new StringBuilder();
            merchandiseName.append(merchandises[0]).append("等");
        }

        orderRepository.saveAndFlush(order);
        itemRepository.saveAll(items);

        lifeCycleService.saveLifeCycle(orderCode, null, "订单已提交", "订单提交成功");

        //调用微信支付接口

        return payService.unifiedOrder(request, merchantName + "-" + merchandiseName.toString(), totalAmount.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString(), orderCode);
    }

    /**
     * @param sku
     * @apiNote 获取sku对应的商品规格描述
     * @author 董兴
     * @date 2020-11-07
     */
    public String getSpecificationBySku(MerchandiseSku sku) {
        StringBuilder builder = new StringBuilder();
        QMerchandiseSku qMerchandiseSku = QMerchandiseSku.merchandiseSku;
        QMerchandiseAttributes qMerchandiseAttributes = QMerchandiseAttributes.merchandiseAttributes;
        QAttributeOptions qAttributeOptions = QAttributeOptions.attributeOptions;
        QSkuOptionsRelationship qSkuOptionsRelationship = QSkuOptionsRelationship.skuOptionsRelationship;
        jpaQueryFactory.select(qMerchandiseSku.skuCode, qMerchandiseAttributes.attributeName, qAttributeOptions.optionName)
            .from(qMerchandiseSku)
            .leftJoin(qSkuOptionsRelationship).on(qMerchandiseSku.skuCode.eq(qSkuOptionsRelationship.skuCode))
            .leftJoin(qAttributeOptions).on(qAttributeOptions.optionCode.eq(qSkuOptionsRelationship.optionCode))
            .leftJoin(qMerchandiseAttributes).on(qMerchandiseAttributes.attributeCode.eq(qAttributeOptions.attributeCode))
            .where(qMerchandiseSku.status.eq(true)
                .and(qMerchandiseSku.skuCode.eq(sku.getSkuCode()))
                .and(qMerchandiseAttributes.status.eq(true).or(qMerchandiseAttributes.attributeName.eq("默认")))
                .and(qAttributeOptions.status.eq(true)))
            .fetch()
            .forEach(tuple -> {
                builder.append(tuple.get(qAttributeOptions.optionName)).append("/");
            });
        if (builder.length() > 0) {
            builder.deleteCharAt(builder.length() - 1);
        }
        return builder.toString();
    }
}
